package com.moodbox.server.common.interceptor;

import cn.hutool.core.util.StrUtil;
import com.moodbox.server.common.annotation.RequireRole;
import com.moodbox.server.common.enums.UserRoleEnum;
import com.moodbox.server.common.exception.AuthorizationException;
import com.moodbox.server.user.entity.User;
import com.moodbox.server.user.service.UserService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.Key;

@Slf4j
@Component
@RequiredArgsConstructor
public class TokenAuthInterceptor implements HandlerInterceptor {

    private final UserService userService;
    private final Key jwtSecretKey;

    @Override
    public boolean preHandle(
        HttpServletRequest request, 
        HttpServletResponse response, 
        Object handler
    ) throws Exception {
        // 非方法直接放行
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        
        // 检查是否需要权限验证
        RequireRole requireRole = handlerMethod.getMethodAnnotation(RequireRole.class);
        
        // 获取Token
        String authHeader = request.getHeader("Authorization");
        
        // 公开接口不需要Token
        if (requireRole == null && StrUtil.isBlank(authHeader)) {
            return true;
        }

        // 需要Token但未提供
        if (StrUtil.isBlank(authHeader)) {
            throw new AuthorizationException("未提供认证Token");
        }
        
        // 处理Bearer前缀
        String token = authHeader;
        if (authHeader.startsWith("Bearer ")) {
            token = authHeader.substring(7);
        }

        try {
            // 解析Token
            Claims claims = Jwts.parserBuilder()
                .setSigningKey(jwtSecretKey)
                .build()
                .parseClaimsJws(token)
                .getBody();

            // 获取用户ID和角色
            String userId = claims.getSubject();
            Integer roleCode = claims.get("role", Integer.class);
            UserRoleEnum userRole = UserRoleEnum.getByCode(roleCode);

            // 验证用户是否存在
            User user = userService.getUserById(userId);
            if (user == null) {
                throw new AuthorizationException("用户不存在");
            }

            // 如果需要特定角色权限
            if (requireRole != null) {
                if (requireRole.strict()) {
                    // 严格匹配
                    if (userRole != requireRole.value()) {
                        throw new AuthorizationException("权限不足");
                    }
                } else {
                    // 最小权限匹配
                    if (userRole.getCode() < requireRole.value().getCode()) {
                        throw new AuthorizationException("权限不足");
                    }
                }
            }

            // 将用户ID放入请求属性，后续可以使用
            request.setAttribute("userId", userId);
            request.setAttribute("userRole", userRole);

            log.info("用户{}通过Token认证", userId);
            return true;

        } catch (Exception e) {
            log.error("Token认证失败", e);
            throw new AuthorizationException("无效的认证Token：" + e.getMessage());
        }
    }
} 